/**
 * @package ztFileInput
 * @version SVN: $Id: jquery.ztfileinput.js 18 2012-10-24 12:53:54Z trulec@gmail.com $
 * 
 * original- / source-project: ----------------------------------------
 * jQuery customfileinput plugin
 * http://filamentgroup.com/lab/jquery_custom_file_input_book_designing_with_progressive_enhancement/
 * Author: Scott Jehl, scott@filamentgroup.com
 * Copyright (c) 2009 Filament Group 
 * licensed under MIT (filamentgroup.com/examples/mit-license.txt)
 * --------------------------------------------------------------------
 */
/**
 * jQuery ztFileInput plugin
 * 
 * 
 * 
 * @package ztFileInput
 * @subpackage JS core-file
 * @author  Scott Jehl, Zeljko Trulec
 * @date    06.03.2012
 * @copyright 2010-2012 changes by Zeljko Trulec (ztProjects)
 * 
 */

(function($) {
	
	// can be overridden by element-attributes
	var ztFileInputOptions = {
			maxfiles: 1,                  // number of max files to upload; -1=unlimited; 0=disabled, default=1
			duplicates: false,            // TRUE: check if filename is already selected, FALSE: duplicates allowed
			extAllowed: false,            // Allowed File-Extensions: e.g. "gif|jpg|png|bmp"
			extForbidden: false           // Forbidden File-Extensions: e.g. "js|html|xml"
	};
	
	var ztFileInputMethods = {
		init: function(options){
			if(!$(this).is('input:file')) return false; // just input-file-fields
			
			var container = $(this);
			// options-object
			var opts = {
					maxfiles:     null,
					duplicates:   null,
					extallowed:   null,
					extforbidden: null
			}
			
			// collecting possible element-attributes
			var cOpts = {
					maxfiles:     container.attr('maxfiles'),
					duplicates:   container.attr('duplicates'),
					extallowed:   container.attr('extallowed'),
					extforbidden: container.attr('extforbidden')
			}
			
			
			// collecting options sorted by priority:
			// 1. attributes of element,
			// 2. arguments passed in functioncall
			// 3. script-defaults
			$.extend(opts, ztFileInputOptions, options, cOpts);
			
			if (isNaN(opts.maxfiles)) opts.maxfiles = 1;
			if (opts.duplicates == "true" || opts.duplicates === true) opts.duplicates = true;
			else opts.duplicates = false;
			
			
			// apply events and styles for file input element
			var fileInput = $(this)
				.addClass('ztfile-input') //add class for CSS
				.mouseover(function(){ upload.addClass('ztfile-hover'); })
				.mouseout(function(){ upload.removeClass('ztfile-hover'); })
				.focus(function(){
					upload.addClass('ztfile-focus'); 
					fileInput.data('val', fileInput.val());
				})
				.blur(function(){
					upload.removeClass('ztfile-focus');
				})
				.bind('disable',function(){
					fileInput.attr('disabled',true);
					upload.addClass('ztfile-disabled');
					uploadButtonContainer.fadeTo('fast', 0.1);
				})
				.bind('enable',function(){
					fileInput.removeAttr('disabled');
					upload.removeClass('ztfile-disabled');
					uploadButtonContainer.fadeTo('fast', 1);
				})
				.bind('checkChange', function(){
					if(!isPresent && fileInput.val() && fileInput.val() != fileInput.data('val')){
						fileInput.trigger('change');
					}
					isPresent = false;
				})
				.bind('change',function(){
					// get file name
					var fileName = $(this).val().split(/\\/).pop();
					
					// check for duplicates
					if (opts.duplicates === false) {
						$('#ztfile-button-container input[id^=ztfile_id_]:file').each(function(){
							if (fileName == $(this).val().split(/\\|\//).pop()) {
								isPresent = true;
								return;
							}
						});
					}
					if (isPresent) {
						$(this).data('val', '');
						alert('Die Datei ist bereits enthalten');
						fileInput.blur();
						isPresent = false;
						return;
					}
					
					// get file extension
					var fileExt = fileName.split('.').pop().toLowerCase();
					
					// just allowed extensions
					if (opts.extallowed != null && !RegExp(opts.extallowed.toLowerCase()).test(fileExt)) {
						alert("Der Dateityp ist nicht erlaubt.");
						return;
					}
					
					// no forbidden extensions
					if (opts.extforbidden != null && RegExp(opts.extforbidden.toLowerCase()).test(fileExt)) {
						alert("Der Dateityp ist nicht erlaubt.");
						return;
					}
					
					// file-extension-css-class
					var fileExtClass = 'ztfile-ext-' + fileExt;
					
					// if no element was found up to now
					if (fileUploadListLength == 0)
						uploadFeedbackEmpty.remove();
					
					var oldFileExtClass = uploadFeedback.data('fileExtClass');
					uploadFeedback = uploadFeedback.clone(true);
					
					// update the feedback
					uploadFeedback
						.removeClass(oldFileExtClass || '') //remove any existing file extension class
						.addClass(fileExtClass) //add file extension class
						.data('fileExtClass', fileExtClass) //store file extension for class removal on next change
						.addClass('ztfile-feedback-populated') //add class to show populated state
						.unbind()
						.attr('title', 'Datei von der Liste entfernen')
						.attr('id', 'ztfile_listid_' + fileUploadListID)
						.data('elemNum', fileUploadListID)
						.hover(function(){$(this).addClass('ztfile-feedback-hover');},      // mousein-icon
									 function(){$(this).removeClass('ztfile-feedback-hover');})   // mouseout-icon
						.click(function(){  // remove element from list
							var elemID = $(this).data('elemNum');
							$('#ztfile_id_'+elemID+':input, #ztfile_listid_' + elemID).remove();
							fileUploadListLength--;
							if (fileUploadListLength == 0)
								uploadFeedbackEmpty.appendTo(upload);
							
							// activate
							if (fileUploadListLength < opts.maxfiles)
								fileInput.trigger('enable');
						})
						.contents('.ztfile-feedback-text')
						.remove();
					
					// add files to the list
					uploadFeedbackFile = uploadFeedbackFile
						.clone(true)
						.text(fileName)
						.appendTo(uploadFeedback);
					upload.append(uploadFeedback);
					
					// create new File-Input
					var newInput = $(this)
						.clone(true)
						.appendTo(uploadButtonContainer)
						.val('');
					// move current File-Input outer visible
					$(this).css({
						'left': 0,
						'top': -3000
					});
					
					// give it an ID to identify
					fileInput.attr('id', 'ztfile_id_' + fileUploadListID);
					// count listlength
					fileUploadListLength++;
					fileUploadListID++;
					
					// set new as current element
					fileInput = newInput;
					fileInput.css({
						'left': uploadButtonContainer.offset().left,
						'top': uploadButtonContainer.offset().top
					});
					
					// deactivate if necessary
					if (opts.maxfiles != -1 && fileUploadListLength >= opts.maxfiles) {
						fileInput.trigger('disable');
					}
					else fileInput.trigger('enable');
					
					fileInput.blur();
					uploadFeedback.removeClass('ztfile-feedback-hover');
				})
				.click(function(){ //for IE and Opera, make sure change fires after choosing a file, using an async callback
					fileInput.data('val', fileInput.val());
					setTimeout(function(){
						fileInput.trigger('checkChange');
					},100);
				});
				
			//create custom control container
			var upload = $('<div class="ztfile"></div>');
			//create custom control button
			var uploadButtonContainer = $('<div id="ztfile-button-container"></div>').appendTo(upload);
			var uploadButton = $('<div class="ztfile-button" id="ztfile-button"></div>').appendTo(uploadButtonContainer);
			//create custom control feedback
			var uploadFeedbackEmpty = $('<div class="ztfile-feedback-empty"><div class="ztfile-feedback-text">Nichts gewählt...</div></div>').appendTo(upload);
			var uploadFeedback = $('<div class="ztfile-feedback"><div class="ztfile-feedback-populated-delete-icon"></div></div>');
			var uploadFeedbackFile = $('<div class="ztfile-feedback-text"></div>').appendTo(uploadFeedback);
			
			// div params
			var fileUploadListLength = 0;
			var fileUploadListID = 1000;
			var isPresent = false;
			
			// match disabled state
			// deactivate if necessary
			if(fileInput.is('[disabled]') || (opts.maxfiles != "-1" && fileUploadListLength >= opts.maxfiles)){
				fileInput.trigger('disable');
			}
			
			// on mousemove, keep file input under the cursor to steal click
			uploadButtonContainer.mousemove(function(e){
				
				// If the mouseposition is within the button-container, move the inputfield under the pointer, else move it out
				if (e.pageY >= uploadButtonContainer.offset().top &&
					e.pageY <= (uploadButtonContainer.offset().top+uploadButtonContainer.height()) &&
					e.pageX >= uploadButtonContainer.offset().left &&
					e.pageX <= (uploadButtonContainer.offset().left+uploadButtonContainer.width())) {
					
					//test...
					//uploadFeedbackEmpty.text(e.pageY + " - " + uploadButtonContainer.offset().top + " - " + (fileInput.height()/2));
					
					fileInput.css({
						'left': e.pageX - uploadButtonContainer.offset().left - fileInput.outerWidth() + 30, //position right side 20px right of cursor X)
						'top': e.pageY - uploadButtonContainer.offset().top - (fileInput.height()/2) //center-height of the button
						//'top': e.pageY - uploadButtonContainer.offset().top - $(window).scrollTop() - (fileInput.height()/2) //center-height of the button
					});
				}
				else {
					fileInput.css({
						'left': 1000,
						'top': 1000
					});
				}
			});
			upload.insertAfter(fileInput); //insert after the input
			fileInput.appendTo(uploadButtonContainer);
			
			// kill the last empty element on submit
			fileInput.parents('form').bind("submit", function(){
				$('.ztfile input:file:last', this).remove();
			});
			
			//return jQuery
			return $(this);
		}
	};
	
	/**
	 * constructor to chek for init or method-call
	 */
	$.fn.ztFileInput = function( method ) {
		
		// call a method
		if ( ztFileInputMethods[method] ) {
			return ztFileInputMethods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
		}
		
		// initialize
		else return ztFileInputMethods.init.apply( this, arguments );
		
	};
	
})(jQuery);